﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Jay.Sc2.Bof.Lib;
using Jay.Sc2.Bof.Lib.Action;
using Jay.Sc2.Bof.Lib.Action.Zerg;
using Jay.Sc2.Bof.Lib.Action.Terran;
using Jay.Sc2.Bof.Lib.Action.Protoss;
using Jay.Sc2.Bof.Lib.Tools;

namespace Jay.Sc2.Bof.Windows
{
	public partial class ConfigurationForm : Form
	{

		private BuildOrderFinder m_Finder;
		private List<IMutater> m_Mutaters = new List<IMutater>();
		private List<IReproducer> m_Reproducer = new List<IReproducer>();

		public ConfigurationForm()
		{
			InitializeComponent();

			m_Mutaters.Add(new DefaultMutater());
			m_Mutaters.Add(new RandomAddActionMutater(0.30, new List<IAction>(Program.CurrentRace.Actions)));
			m_Mutaters.Add(new RandomRemoveActionMutater(0.30));
			m_Mutaters.Add(new RandomMoveActionMutater(0.30));

			m_Reproducer.Add(new DefaultReproducer());
			m_Reproducer.Add(new RandomReproducer());
			m_Reproducer.Add(new RandomSplitReproducer());
			m_Reproducer.Add(NewBuildReproducer.Instance);


		}
		private void RefreshMutaters()
		{
			lvMutaters.Items.Clear();
			foreach (IMutater mutater in m_Mutaters)
			{
				ListViewItem item = new ListViewItem(new string[] { mutater.Name });
				item.Tag = mutater;
				if (m_Finder != null && m_Finder.m_Mutaters.Contains(mutater))
					item.Checked = true;
				lvMutaters.Items.Add(item);
			}
		}
		private void RefreshPreproducers()
		{
			lvReproducers.Items.Clear();
			foreach (IReproducer reproducer in m_Reproducer)
			{
				ListViewItem item = new ListViewItem(new string[] { reproducer.Name });
				item.Tag = reproducer;
				if (m_Finder != null && m_Finder.m_Reproducers.Contains(reproducer))
					item.Checked = true;
				lvReproducers.Items.Add(item);
			}
		}
		public ConfigurationForm(BuildOrderFinder finder)
			: this()
		{
			m_Finder = finder;
			if (m_Finder.m_Mutaters == null)
				m_Finder.GenerateDefaultOperators();
			tbMaxActions.Text = m_Finder.m_MaxActionListSize.ToString();
			tbSubsetSize.Text = m_Finder.m_SubsetSize.ToString();
			tbMutaters.Text = m_Finder.m_Mutaters.Count.ToString();
			tbReproducers.Text = m_Finder.m_Reproducers.Count.ToString();
			tbPopulation.Text = (((m_Finder.m_SubsetSize * m_Finder.m_SubsetSize) / 2) *
				m_Finder.m_Mutaters.Count * m_Finder.m_Reproducers.Count * 2).ToString();
			tbFailedCount.Text = m_Finder.m_FailedCount.ToString();
			if(Program.CurrentRace == TerranRace.Instance) cbAutoCall.Checked = m_Finder.m_AutoActions != null && m_Finder.m_AutoActions.Contains(ActionCallMule.Instance);
			if (Program.CurrentRace == ZergRace.Instance) cbAutoCall.Checked = m_Finder.m_AutoActions != null && m_Finder.m_AutoActions.Contains(ActionCallSpawnLarvae.Instance);
			if (Program.CurrentRace == TerranRace.Instance) cbAutoHarvester.Checked = m_Finder.m_AutoActions != null && m_Finder.m_AutoActions.Contains(ActionProduceSCV.Instance);
			if (Program.CurrentRace == ZergRace.Instance) cbAutoHarvester.Checked = m_Finder.m_AutoActions != null && m_Finder.m_AutoActions.Contains(ActionProduceDrone.Instance);
			if (Program.CurrentRace == ProtossRace.Instance) cbAutoHarvester.Checked = m_Finder.m_AutoActions != null && m_Finder.m_AutoActions.Contains(ActionProduceProbe.Instance);

			foreach (IMutater mutater in m_Finder.m_Mutaters)
			{
				if (!m_Mutaters.Contains(mutater))
					m_Mutaters.Add(mutater);
			}
			foreach (IReproducer reproducer in m_Finder.m_Reproducers)
			{
				if (!m_Reproducer.Contains(reproducer))
					m_Reproducer.Add(reproducer);
			}
			RefreshMutaters();
			RefreshPreproducers();
		}

		private void bSave_Click(object sender, EventArgs e)
		{
			m_Finder.m_MaxActionListSize = int.Parse(tbMaxActions.Text);
			m_Finder.m_SubsetSize = int.Parse(tbSubsetSize.Text);
			m_Finder.m_FailedCount = int.Parse(tbFailedCount.Text);
			List<IAction> auto = new List<IAction>();
			switch (Program.CurrentRace.Name)
			{
				case "Zerg":
					if(cbAutoCall.Checked) auto.Add(ActionCallSpawnLarvae.Instance);
					if(cbAutoHarvester.Checked) auto.Add(ActionProduceDrone.Instance);
					break;
				case "Terran":
					if (cbAutoCall.Checked) auto.Add(ActionCallMule.Instance);
					if (cbAutoHarvester.Checked) auto.Add(ActionProduceSCV.Instance);
					break;
				case "Protoss":
					if (cbAutoHarvester.Checked) auto.Add(ActionProduceProbe.Instance);
					break;
			}
			if (auto.Count == 0) m_Finder.m_AutoActions = null;
			else m_Finder.m_AutoActions = auto;
			m_Finder.m_Scouting.Clear();
			try
			{
				if (cbScouting.Checked)
				{
					Scouting scouting = new Scouting();
					if (rbScoutFood.Checked)
						scouting.Food = int.Parse(tbFoodCount.Text);
					else
						scouting.Time = int.Parse(tbStartTime.Text);
					if (rbScoutDies.Checked)
						scouting.Died = true;
					scouting.TimeEnd = int.Parse(tbEndTime.Text);
					m_Finder.m_Scouting.Add(scouting);
				}
				Close();
			}
			catch (Exception exc)
			{
				MessageBox.Show(this, "Unable to create scout : " + exc.Message + ".", "Scout Error.");
			}
		}

		private void Config_TextChanged(object sender, EventArgs e)
		{
			try
			{
				tbPopulation.Text = (int.Parse(tbSubsetSize.Text) * int.Parse(tbSubsetSize.Text) *
					m_Finder.m_Mutaters.Count * m_Finder.m_Reproducers.Count).ToString();
			}
			catch
			{
			}
		}

		private void lvReproducers_ItemChecked(object sender, ItemCheckedEventArgs e)
		{
			IReproducer reproducer = e.Item.Tag as IReproducer;
			if (m_Finder != null)
			{
				if (e.Item.Checked) m_Finder.m_Reproducers.Add(reproducer);
				else m_Finder.m_Reproducers.Remove(reproducer);
				tbReproducers.Text = m_Finder.m_Reproducers.Count.ToString();
			}
		}

		private void lvMutaters_ItemChecked(object sender, ItemCheckedEventArgs e)
		{
			IMutater mutater = e.Item.Tag as IMutater;
			if (m_Finder != null)
			{
				if (e.Item.Checked) m_Finder.m_Mutaters.Add(mutater);
				else m_Finder.m_Mutaters.Remove(mutater);
				tbMutaters.Text = m_Finder.m_Mutaters.Count.ToString();
			}
		}

		private void ConfigurationForm_Shown(object sender, EventArgs e)
		{
			cbAutoCall.Enabled = true;
			switch (Program.CurrentRace.Name)
			{
				case "Zerg":
					cbAutoCall.Text = "Auto Spawn Larva.";
					cbAutoHarvester.Text = "Auto Produce Drone.";
					break;
				case "Terran":
					cbAutoCall.Text = "Auto Call Mule.";
					cbAutoHarvester.Text = "Auto Produce SCV.";
					break;
				case "Protoss":
					cbAutoCall.Text = "Auto Chrono Boost.";
					cbAutoCall.Checked = false;
					cbAutoCall.Enabled = false;
					cbAutoHarvester.Text = "Auto Produce Probe.";
					break;
			}
		}

		private void ScoutStart_CheckedChanged(object sender, EventArgs e)
		{
			tbFoodCount.Enabled = rbScoutFood.Checked;
			tbStartTime.Enabled = rbScoutTime.Checked;
		}

		private void cbScouting_CheckedChanged(object sender, EventArgs e)
		{
			tbFoodCount.Enabled = cbScouting.Checked;
			tbStartTime.Enabled = cbScouting.Checked;
			tbEndTime.Enabled = cbScouting.Checked;
			rbScoutTime.Enabled = cbScouting.Checked;
			rbScoutComesBack.Enabled = cbScouting.Checked;
			rbScoutDies.Enabled = cbScouting.Checked;
			rbScoutFood.Enabled = cbScouting.Checked;
			rbScoutTime.Enabled = cbScouting.Checked;
			if (cbScouting.Checked) ScoutStart_CheckedChanged(sender, e);
		}
	}
}
